package cn.iocoder.yudao.module.infrastructure.messy.controller.app;

import cn.hutool.core.util.StrUtil;
import cn.iocoder.yudao.framework.business.basic.pojo.vo.UserSimpleVO;
import cn.iocoder.yudao.framework.qrcode.pojo.*;
import cn.iocoder.yudao.framework.qrcode.util.QrCodeUtils;
import cn.iocoder.yudao.module.api.member.agency.AgencyUserApi;
import cn.iocoder.yudao.module.api.member.agency.vo.AgencyUserVO;
import cn.iocoder.yudao.module.api.member.user.MemberUserApi;
import cn.iocoder.yudao.module.api.pay.bill.enums.BillCategoryEnum;
import cn.iocoder.yudao.module.api.shop.info.ShopInfoApi;
import cn.iocoder.yudao.module.api.shop.info.dto.ShopInfoDTO;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter;
import jakarta.annotation.Nonnull;
import jakarta.annotation.Resource;
import jakarta.annotation.security.PermitAll;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestParam;

import static cn.iocoder.yudao.framework.security.core.util.SecurityFrameworkUtils.getLoginUserId;

@Slf4j
public abstract class AppBaseCodeController {
    @Resource
    private MemberUserApi memberUserApi;
    @Resource
    private AgencyUserApi agencyUserApi;
    @Resource
    private ShopInfoApi shopInfoApi;

    @GetMapping("/invite")
    @Operation(summary = "生成用户身份码", description = "登录状态若未明确传用户身份码，则自动获取当前登录用户的身份码")
    @Parameter(name = "memberNo", description = "用户身份码")
    @PermitAll
    public String invite(@RequestParam(value = "memberNo", required = false) String memberNo) {
        if (StrUtil.isBlank(memberNo)) {
            Long userId = getLoginUserId();
            if (userId == null || userId <= 0) {
                log.error("用户身份码生成失败：未传递用户身份码且用户未登录");
                return "";
            }
            UserSimpleVO userRespDTO = memberUserApi.getUser(userId);
            if (userRespDTO == null) {
                log.error("用户身份码生成失败：未获取到或未传递用户身份码");
                return "";
            }
            memberNo = userRespDTO.getNo();
        }
        QrCodeInviteType type = new QrCodeInviteType();
        type.setMemberNo(memberNo);
        return generatePngAsUri(type);
    }

    @GetMapping("/verify")
    @Operation(summary = "生成订单核销码")
    @Parameter(name = "verifyCode", description = "核销码", required = true)
    @PermitAll
    public String verify(@RequestParam("verifyCode") String verifyCode) {
        QrCodeVerifyType type = new QrCodeVerifyType();
        type.setVerifyCode(verifyCode);
        return generatePngAsUri(type);
    }

    @GetMapping("/payment")
    @Operation(summary = "生成商家收款码", description = "登录状态若未明确传店铺编号，则自动获取当前登录用户关联的店铺编号")
    @Parameter(name = "shopId", description = "店铺编号")
    @Parameter(name = "memberNo", description = "用户身份码")
    @PermitAll
    public String payment(@RequestParam(value = "shopId", required = false) Long shopId, @RequestParam(value = "memberNo", required = false) String memberNo) {
        if (shopId == null) {
            Long userId = getLoginUserId();
            if (userId == null || userId <= 0) {
                log.error("商家收款码生成失败：未传递店铺编号且用户未登录");
                return "";
            }
            UserSimpleVO userRespDTO = memberUserApi.getUser(userId);
            if (userRespDTO != null) {
                memberNo = userRespDTO.getNo();
            }
            ShopInfoDTO shopInfoRespDTO = shopInfoApi.getShopInfoByMemberUserId(userId);
            if (shopInfoRespDTO == null) {
                log.error("商家收款码生成失败：未获取到或未传递店铺编号");
                return "";
            }
            shopId = shopInfoRespDTO.getId();
        }
        QrCodePaymentType type = new QrCodePaymentType();
        type.setShopId(shopId);
        type.setMemberNo(memberNo == null ? "" : memberNo);
        return generatePngAsUri(type);
    }

    @GetMapping("/dinein")
    @Operation(summary = "生成堂食点餐码", description = "登录状态若未明确传店铺编号，则自动获取当前登录用户关联的店铺编号")
    @Parameter(name = "shopId", description = "店铺编号")
    @Parameter(name = "deskNo", description = "餐桌号", required = true)
    @Parameter(name = "memberNo", description = "用户身份码")
    @PermitAll
    public String dinein(@RequestParam(value = "shopId", required = false) Long shopId, @RequestParam("deskNo") String deskNo, @RequestParam(value = "memberNo", required = false) String memberNo) {
        if (shopId == null) {
            Long userId = getLoginUserId();
            if (userId == null || userId <= 0) {
                log.error("堂食点餐码生成失败：未传递店铺编号且用户未登录");
                return "";
            }
            UserSimpleVO userRespDTO = memberUserApi.getUser(userId);
            if (userRespDTO != null) {
                memberNo = userRespDTO.getNo();
            }
            ShopInfoDTO shopInfoRespDTO = shopInfoApi.getShopInfoByMemberUserId(userId);
            if (shopInfoRespDTO == null) {
                log.error("堂食点餐码生成失败：未获取到或未传递店铺编号");
                return "";
            }
            shopId = shopInfoRespDTO.getId();
        }
        QrCodeDineInType type = new QrCodeDineInType();
        type.setShopId(shopId);
        type.setDeskNo(deskNo);
        type.setMemberNo(memberNo == null ? "" : memberNo);
        return generatePngAsUri(type);
    }

    @GetMapping("/takeout")
    @Operation(summary = "生成外卖点餐码", description = "登录状态若未明确传店铺编号，则自动获取当前登录用户关联的店铺编号")
    @Parameter(name = "shopId", description = "店铺编号")
    @Parameter(name = "memberNo", description = "用户身份码")
    @PermitAll
    public String takeout(@RequestParam(value = "shopId", required = false) Long shopId, @RequestParam(value = "memberNo", required = false) String memberNo) {
        if (shopId == null) {
            Long userId = getLoginUserId();
            if (userId == null || userId <= 0) {
                log.error("外卖点餐码生成失败：未传递店铺编号且用户未登录");
                return "";
            }
            UserSimpleVO userRespDTO = memberUserApi.getUser(userId);
            if (userRespDTO != null) {
                memberNo = userRespDTO.getNo();
            }
            ShopInfoDTO shopInfoRespDTO = shopInfoApi.getShopInfoByMemberUserId(userId);
            if (shopInfoRespDTO == null) {
                log.error("外卖点餐码生成失败：未获取到或未传递店铺编号");
                return "";
            }
            shopId = shopInfoRespDTO.getId();
        }
        QrCodeTakeoutType type = new QrCodeTakeoutType();
        type.setShopId(shopId);
        type.setMemberNo(memberNo == null ? "" : memberNo);
        return generatePngAsUri(type);
    }

    @GetMapping("/agency")
    @Operation(summary = "生成招商推广码", description = "登录状态若未明确传招商人员编号，则自动获取当前登录用户的招商人员编号")
    @Parameter(name = "agencyId", description = "招商人员编号")
    @Parameter(name = "memberNo", description = "用户身份码")
    @PermitAll
    public String agency(@RequestParam(value = "agencyId", required = false) Long agencyId, @RequestParam(value = "memberNo", required = false) String memberNo) {
        if (agencyId == null) {
            Long userId = getLoginUserId();
            if (userId == null || userId <= 0) {
                log.error("招商推广码生成失败：未传递招商人员编且用户未登录");
                return "";
            }
            UserSimpleVO userRespDTO = memberUserApi.getUser(userId);
            if (userRespDTO != null) {
                memberNo = userRespDTO.getNo();
            }
            AgencyUserVO agencyUserRespDTO = agencyUserApi.getAgencyUserByUserId(userId);
            if (agencyUserRespDTO == null) {
                log.error("招商推广码生成失败：未获取到或未传递招商人员编号");
                return "";
            }
            agencyId = agencyUserRespDTO.getId();
        }
        QrCodeAgencyType type = new QrCodeAgencyType();
        type.setAgencyId(agencyId);
        type.setMemberNo(memberNo == null ? "" : memberNo);
        return generatePngAsUri(type);
    }

    @GetMapping("/purchase")
    @Operation(summary = "生成商圈进货码")
    @Parameter(name = "investorId", description = "聚商圈投资人编号")
    @Parameter(name = "memberNo", description = "业务员用户身份码")
    @PermitAll
    public String purchase(@RequestParam(value = "investorId", required = false) Long investorId, @RequestParam(value = "memberNo", required = false) String memberNo) {
        if (StrUtil.isBlank(memberNo)) {
            Long userId = getLoginUserId();
            if (userId == null || userId <= 0) {
                log.error("商圈进货码生成失败：未传递招商人员编且用户未登录");
                return "";
            }
            UserSimpleVO userRespDTO = memberUserApi.getUser(userId);
            if (userRespDTO == null) {
                log.error("商圈进货码生成失败：未获取到或未传递用户身份码");
                return "";
            }
            memberNo = userRespDTO.getNo();
        }
        QrCodePurchaseType type = new QrCodePurchaseType();
        type.setInvestorId(investorId);
        type.setMemberNo(memberNo);
        return generatePngAsUri(type);
    }

    @GetMapping("/transfer")
    @Operation(summary = "生成资产转赠码", description = "目前只支持收益豆转赠")
    @Parameter(name = "userId", description = "用户编号")
    @Parameter(name = "category", description = "资产种类：cryptocurrency_increment-收益豆")
    @PermitAll
    public String transfer(@RequestParam(value = "userId", required = false) Long userId, @RequestParam(value = "category", required = false, defaultValue = "cryptocurrency_increment") String category, @RequestParam("amount") Integer amount) {
        if (userId == null) {
            userId = getLoginUserId();
            if (userId == null || userId <= 0) {
                log.error("资产转赠码生成失败：未传递招商人员编且用户未登录");
                return "";
            }
            UserSimpleVO userRespDTO = memberUserApi.getUser(userId);
            if (userRespDTO == null) {
                log.error("资产转赠码生成失败：未获取到或未传递用户编号");
                return "";
            }
            userId = userRespDTO.getId();
        }
        if (StrUtil.isBlank(category)) {
            category = BillCategoryEnum.CRYPTOCURRENCY_INCREMENT.getCode();
        }
        QrCodeTransferType type = new QrCodeTransferType();
        type.setUserId(userId);
        type.setCategory(category);
        type.setAmount(amount);
        return generatePngAsUri(type);
    }

    @Nonnull
    protected <T extends QrCodeDataType> String generatePngAsUri(T type) {
        return QrCodeUtils.generatePngAsUri(type);
    }

//    @GetMapping("/handle")
//    @Operation(summary = "处理二维码内容", description = "自动解析二维码内容并处理相关业务逻辑")
//    @PermitAll
//    public void handle(@Valid AppQrCodeHandleReqVO reqVO, HttpServletResponse response, HttpServletRequest request) throws IOException {
//        String decrypt = QrCodeUtils.decryptData(reqVO.getData());
//        log.debug("[handle] 原始数据 {} 解析到的二维码内容：{}", reqVO.getData(), decrypt);
//        String userAgent = request.getHeader("User-Agent");
//        // Mozilla/5.0 (Linux; Android 14; PHS110 Build/RKQ1.211119.001; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/116.0.0.0 Mobile Safari/537.36 XWEB/1160117 MMWEBSDK/20240404 MMWEBID/3650 MicroMessenger/8.0.49.2600(0x2800313B) WeChat/arm64 Weixin NetType/WIFI Language/zh_CN ABI/arm64
//        if (userAgent == null || !userAgent.contains("MicroMessenger")) {
//            // 如果不是微信扫码，则返回网页提示
//            response.setContentType("text/html;charset=UTF-8");
//            response.getWriter().write("""
//                    <!DOCTYPE html>
//                    <html lang='zh-CN'>
//                    <head>
//                    <meta charset='utf-8' />
//                    <meta content='pc,mobile' name='applicable-device' />
//                    <meta content="IE=edge" http-equiv="X-UA-Compatible" />
//                    </head>
//                    <body>
//                    <h1 style="text-align:center;margin:30px;">请使用微信扫码，暂不支持其他扫码工具！</h1>
//                    </body>
//                    </html>
//                    """);
//            return;
//        }
//        // 如果是微信扫码，则返回解密后的数据
//        response.setContentType("application/json;charset=UTF-8");
//        // TODO 根据解析后的数据进行业务处理
//        response.getWriter().write(decrypt);
//    }

}
